﻿using UnityEngine;
using UnityEngine.EventSystems;

public class UIEventListener : EventTrigger
{
    public delegate void VoidDelegate(UIEventListener listener);

    public VoidDelegate onPointerClick;
    public VoidDelegate onPointerDown;
    public VoidDelegate onPointerEnter;
    public VoidDelegate onPointerExit;
    public VoidDelegate onPointerUp;

    public VoidDelegate onInitializePotentialDrag;
    public VoidDelegate onBeginDrag;
    public VoidDelegate onDrag;
    public VoidDelegate onEndDrag;
    public VoidDelegate onDrop;

    public VoidDelegate onMove;
    public VoidDelegate onScroll;

    public VoidDelegate onSelect;
    public VoidDelegate onDeselect;
    public VoidDelegate onUpdateSelected;

    public VoidDelegate onSubmit;
    public VoidDelegate onCancel;

    public object data { get; private set; }
    public BaseEventData eventData { get; private set; }
    public static UIEventListener Get(GameObject go)
    {
        return go.GetComponent<UIEventListener>() ?? go.AddComponent<UIEventListener>();
    }

    public static UIEventListener Get(GameObject go, object data)
    {
        UIEventListener listener = go.GetComponent<UIEventListener>() ?? go.AddComponent<UIEventListener>();
        listener.data = data;
        return listener;
    }

    #region Pointer Events
    public override void OnPointerClick(PointerEventData eventData)
    {
        this.eventData = eventData;
        if (onPointerClick != null) { onPointerClick(this); }
    }

    public override void OnPointerDown(PointerEventData eventData)
    {
        this.eventData = eventData;
        if (onPointerDown != null) { onPointerDown(this); }
    }

    public override void OnPointerEnter(PointerEventData eventData)
    {
        this.eventData = eventData;
        if (onPointerEnter != null) { onPointerEnter(this); }
    }

    public override void OnPointerExit(PointerEventData eventData)
    {
        this.eventData = eventData;
        if (onPointerExit != null) { onPointerExit(this); }
    }

    public override void OnPointerUp(PointerEventData eventData)
    {
        this.eventData = eventData;
        if (onPointerUp != null) { onPointerUp(this); }
    }
    #endregion

    #region DragEvents
    public override void OnInitializePotentialDrag(PointerEventData eventData)
    {
        this.eventData = eventData;
        if (onInitializePotentialDrag != null) { onInitializePotentialDrag(this); }
    }

    public override void OnBeginDrag(PointerEventData eventData)
    {
        this.eventData = eventData;
        if (onBeginDrag != null) { onBeginDrag(this); }
    }

    public override void OnDrag(PointerEventData eventData)
    {
        this.eventData = eventData;
        if (onDrag != null) { onDrag(this); }
    }

    public override void OnEndDrag(PointerEventData eventData)
    {
        this.eventData = eventData;
        if (onEndDrag != null) { onEndDrag(this); }
    }

    public override void OnDrop(PointerEventData eventData)
    {
        this.eventData = eventData;
        if (onDrop != null) { onDrop(this); }
    }
    #endregion

    #region Other Pointer Related Events
    public override void OnMove(AxisEventData eventData)
    {
        this.eventData = eventData;
        if (onMove != null) { onMove(this); }
    }

    public override void OnScroll(PointerEventData eventData)
    {
        this.eventData = eventData;
        if (onScroll != null) { onScroll(this); }
    }
    #endregion

    #region Navigation Events
    public override void OnSelect(BaseEventData eventData)
    {
        this.eventData = eventData;
        if (onSelect != null) { onSelect(this); }
    }

    public override void OnDeselect(BaseEventData eventData)
    {
        this.eventData = eventData;
        if (onDeselect != null) { onDeselect(this); }
    }

    public override void OnUpdateSelected(BaseEventData eventData)
    {
        this.eventData = eventData;
        if (onUpdateSelected != null) { onUpdateSelected(this); }
    }
    #endregion

    #region Other Events
    public override void OnSubmit(BaseEventData eventData)
    {
        this.eventData = eventData;
        if (onSubmit != null) { onSubmit(this); }
    }

    public override void OnCancel(BaseEventData eventData)
    {
        this.eventData = eventData;
        if (onCancel != null) { onCancel(this); }
    }
    #endregion
}